package net.sf.midollo.io.lcdui.textbox;

import java.io.IOException;
import java.io.InputStream;

import javax.microedition.lcdui.TextBox;
import javax.microedition.lcdui.TextField;

public class TextBoxInputStream extends InputStream {

  protected final TextBox textBox;
  protected boolean acceptPending;
  protected byte[] buffer;
  protected int off;

  public TextBoxInputStream(TextBox textBox) {
    this.textBox = textBox;
    this.acceptPending = false;
  }

  public void accept() {
    synchronized (this.textBox) {
      this.acceptPending = true;
      this.textBox.notifyAll();
    }
  }

  public int available() throws IOException {
    synchronized (this.textBox) {
      return fillBuffer();
    }
  }

  public int read() throws IOException {
    byte[] singleByteBuffer = new byte[1];
    int nread = read(singleByteBuffer);
    if (nread <= 0)
      return -1;
    return singleByteBuffer[0];
  }

  public int read(byte[] b) throws IOException {
    return read(b, 0, b.length);
  }

  public int read(byte[] b, int off, int len) throws IOException {
    int avail;
    synchronized (this.textBox) {
      while ((avail = fillBuffer()) <= 0) {
        try {
          this.textBox.wait();
        } catch (InterruptedException ex) {
          return -1;
        }
      }
      if (len > avail)
        len = avail;
      System.arraycopy(this.buffer, this.off, b, off, len);
      this.off += len;
      if (this.off >= this.buffer.length) {
        this.buffer = null;
        this.textBox.delete(0, this.textBox.size());
      }
      return len;
    }
  }

  protected int fillBuffer() {
    if (this.buffer == null) {
      if (this.acceptPending) {
        String str = this.textBox.getString();
        this.off = 0;
        this.buffer = str.getBytes();
        if (this.buffer != null && this.buffer.length > 0) {
          this.acceptPending = false;
          this.textBox.setConstraints(this.textBox.getConstraints() | TextField.UNEDITABLE);
          return this.buffer.length;
        } else {
          this.buffer = null;
        }
      } else {
        this.textBox.setConstraints(this.textBox.getConstraints() & ~TextField.UNEDITABLE);
      }
      return 0;
    }
    return this.buffer.length - this.off;
  }
}
